/**
 * @p.md
 * 
 * RootContext 是 Actor 系统的根上下文，提供创建和管理顶级 Actor 的功能
 */
import { ActorSystem } from './actorSystem';
import { PID } from './pid';
import { Props } from './props';
import * as SystemMessages from './systemMessages';
import { DefaultActorProcess } from './defaultActorProcess';
import { ProcessRegistry } from './processRegistry';

/**
 * RootContext 类提供管理顶级 Actor 的功能
 */
export class RootContext {
  /**
   * 构造函数
   * @param system Actor 系统实例
   */
  constructor(public readonly system: ActorSystem) {}

  /**
   * 创建一个新的 Actor
   * @param props Actor 属性配置
   * @returns 新创建 Actor 的 PID
   */
  spawn(props: Props): PID {
    // 生成唯一 ID
    const name = this.system.processRegistry.nextId();
    return this.spawnNamed(props, name);
  }

  /**
   * 使用指定前缀创建 Actor
   * @param props Actor 属性配置
   * @param prefix ID 前缀
   * @returns 新创建 Actor 的 PID
   */
  spawnPrefix(props: Props, prefix: string): PID {
    const name = `${prefix}${this.system.processRegistry.nextId()}`;
    return this.spawnNamed(props, name);
  }

  /**
   * 使用指定名称创建 Actor
   * @param props Actor 属性配置
   * @param name Actor 名称
   * @returns 新创建 Actor 的 PID
   */
  spawnNamed(props: Props, name: string): PID {
    // 创建 Actor 实例
    const actor = props.producer();
    
    // 获取进程注册表实例
    const processRegistry = ProcessRegistry.getInstance();
    
    // 创建 PID
    const pid = new PID(processRegistry.address(), name);
    
    // 创建 Actor 进程
    const process = new DefaultActorProcess(actor, props, this.system, pid);
    
    // 注册进程并返回 PID
    processRegistry.add(process, name);
    
    return pid;
  }

  /**
   * 停止 Actor
   * @param pid 要停止的 Actor 的 PID
   */
  stop(pid: PID): void {
    pid.stop(this.system);
  }

  /**
   * 发送消息给指定的 Actor
   * @param target 目标 Actor 的 PID
   * @param message 要发送的消息
   */
  send(target: PID, message: any): void {
    // 确保发送的是消息内容而不是函数引用
    if (typeof message === 'function') {
      console.warn('Warning: Attempting to send a function as a message. Converting to object representation.');
      // 将函数转换为可显示的对象
      message = {
        type: 'FunctionMessage',
        name: message.name || 'anonymous',
        description: '函数引用被转换为对象格式'
      };
    }
    target.tell(message, this.system);
  }

  /**
   * 发送请求消息并期望响应
   * @param pid 目标 Actor 的 PID
   * @param message 要发送的消息
   */
  request(pid: PID, message: any): void {
    pid.request(message, this.system);
  }

  /**
   * 发送请求并获取 Future 对象，以异步获取响应
   * @param pid 目标 Actor 的 PID
   * @param message 要发送的消息
   * @param timeout 超时时间（毫秒）
   * @returns 包含响应的 Future 对象
   */
  requestFuture(pid: PID, message: any, timeout: number = 3000) {
    return pid.requestFuture(message, timeout, this.system);
  }

  /**
   * 监视 Actor
   * @param pid 要监视的 Actor 的 PID
   * @param watcher 监视者的 PID
   */
  watch(pid: PID, watcher: PID): void {
    const message = new SystemMessages.Watch(watcher);
    this.sendSystemMessage(pid, message);
  }

  /**
   * 取消监视 Actor
   * @param pid 要取消监视的 Actor 的 PID
   * @param watcher 监视者的 PID
   */
  unwatch(pid: PID, watcher: PID): void {
    const message = new SystemMessages.Unwatch(watcher);
    this.sendSystemMessage(pid, message);
  }

  /**
   * 获取此上下文管理的所有 Actor 的 PID 列表
   * @returns PID 数组
   */
  children(): PID[] {
    // 在实际实现中，应该返回当前上下文下创建的所有 Actor 的 PID
    return [];
  }

  /**
   * 发送系统消息
   * @param pid 目标 Actor 的 PID
   * @param message 系统消息
   */
  private sendSystemMessage(pid: PID, message: any): void {
    const process = this.system.processRegistry.get(pid);
    if (process) {
      process.sendSystemMessage(pid, message);
    }
  }
}

/**
 * RootContext 工厂类
 */
export const RootContexts = {
  /**
   * 创建一个新的 RootContext 实例
   * @param system Actor 系统
   * @returns RootContext 实例
   */
  create(system: ActorSystem): RootContext {
    return new RootContext(system);
  }
}; 